package com.mohan.lucene;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.mohan.controller.MoHanController;
import com.mohan.pojo.Article;
import com.mohan.service.ArticleService;


public class DbIndex {
	private static Logger logger = Logger.getLogger(MoHanController.class);
	
	
	/**
	 * 
	 * @MethodName: buildForSql
	 * @Description: 从数据库获取数据创建索引
	 * @param: MediatService,Directory
	 * @return: void
	 */
	
	public void buildForSql(ArticleService mService,Directory directory){
		try {
			List<Article> articles = mService.getArticles();
			build(articles,directory);
			System.out.println("media size = " + articles.size());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @MethodName: build
	 * @Description: 创建索引(增量索引也是如此)
	 * @param: List<Media>,Directory
	 * @return: void
	 */
	public void build(List<Article> articles, Directory directory){
		IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new IKAnalyzer(true));
		IndexWriter indexWriter = null;
		try {
			indexWriter = new IndexWriter(directory, indexWriterConfig);
			if(articles != null && articles.size() > 0){
				for (Article article : articles) {
					System.out.println("title = " + article.getTitle());
					
					TextField titleField = new TextField("title", article.getTitle(), Field.Store.YES);
					titleField.setBoost(1.0f);
					TextField authorField = new TextField("author", article.getAuthor(), Field.Store.YES);
					authorField.setBoost(2.0f);
					TextField bookField = new TextField("book", article.getBook(), Field.Store.YES);
					bookField.setBoost(3.0f);
					TextField tagsField = new TextField("tags", article.getTags(), Field.Store.YES);
					tagsField.setBoost(3.0f);
					
					Document document = new Document();
					document.add(titleField);
					document.add(authorField);
					document.add(bookField);
					document.add(tagsField);
					
					indexWriter.addDocument(document);
				}
			}			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());
		}finally {
			try {
				indexWriter.commit();
				indexWriter.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				logger.error(e.getMessage());
			}
		}
	}
	
	/**
	 * 
	 * @MethodName: update
	 * @Description: 更新索引
	 * @param: List<Media>,Directory
	 * @return: void
	 */
	public void update(List<Article> articles, Directory directory){
		IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new IKAnalyzer(true));
		IndexWriter indexWriter = null;
		try {
			indexWriter = new IndexWriter(directory, indexWriterConfig);
			if(articles != null && articles.size() > 0){
				for (Article article : articles) {
					TextField titleField = new TextField("title", article.getTitle(), Field.Store.YES);
					titleField.setBoost(1.0f);
					TextField authorField = new TextField("author", article.getAuthor(), Field.Store.YES);
					authorField.setBoost(2.0f);
					TextField bookField = new TextField("book", article.getBook(), Field.Store.YES);
					bookField.setBoost(3.0f);
					TextField tagsField = new TextField("tags", article.getTags(), Field.Store.YES);
					tagsField.setBoost(3.0f);
					
					Document document = new Document();
					document.add(titleField);
					document.add(authorField);
					document.add(bookField);
					document.add(tagsField);
					
					indexWriter.updateDocument(new Term("title", article.getTitle()), document);
				}
			}			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());
		}finally {
			try {
				indexWriter.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				logger.error(e.getMessage());
			}
		}
	}
	
	/**
	 * 
	 * @MethodName: delete
	 * @Description: 删除索引
	 * @param: List<Media>,Directory
	 * @return: void
	 */
	public void delete(List<Article> articles, Directory directory){
		IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new IKAnalyzer(true));
		IndexWriter indexWriter = null;
		try {
			indexWriter = new IndexWriter(directory, indexWriterConfig);
			if(articles != null && articles.size() > 0){
				for (Article article : articles) {
					indexWriter.deleteDocuments(new Term("title", article.getTitle()));
				}
			}			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());
		}finally {
			try {
				indexWriter.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				logger.error(e.getMessage());
			}
		}
	}
	
	/**
	 * 
	 * @MethodName: search
	 * @Description: 搜索索引
	 * @param: Directory
	 * @return: void
	 */
	@SuppressWarnings("finally")
	public List<Article> search(Directory directory, String req, int size){
		DirectoryReader directoryReader = null;
		List<Article> articles = new ArrayList<Article>();
		
		try {
			directoryReader = DirectoryReader.open(directory);		
			IndexSearcher indexSearcher = new IndexSearcher(directoryReader);
			
			String[] fields = {"title", "author", "content", "book", "tags"};  
		
			Query query = new MultiFieldQueryParser(fields, new IKAnalyzer()).parse(req);
			TopDocs topDocs = indexSearcher.search(query, size);
			ScoreDoc[] scoreDocs = topDocs.scoreDocs;
			for (ScoreDoc scoreDoc : scoreDocs) {
				Document d = indexSearcher.doc(scoreDoc.doc);
				System.out.println("score = " + scoreDoc.score + ":::" + d.get("title"));
				if(scoreDoc.score > 0){
					Article article = new Article();
					article.setAuthor(d.get("author"));
					article.setBook(d.get("book"));
					article.setAnalysis(d.get("analysis"));
					article.setLoves(Integer.parseInt(d.get("loves")));
					article.setTags(d.get("tags"));
					article.setTitle(d.get("title"));
					articles.add(article);
				}
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(e.getMessage());
		}finally {
			return articles;
		}
	}
}
